package com.coszero.utils.media

import android.app.Activity
import android.content.Context
import android.media.AudioAttributes
import android.media.AudioManager
import android.media.SoundPool
import android.os.Build
import android.util.Log
import com.coszero.utils.utils.LogX

/**
 * Desc： 音频池工具类,短音频,有缓存池
 *
 * @author xmqian
 * Email:xmqian93@163.com
 * Date: 2021/3/13 0013 17:16
 *
 *
 * SoundPoolUtils.playSoundWithRedId(R.raw.physical_kaishi);
 * @version 1
 */
class SoundPoolUtils(private val mainContext: Context) {
    private val TAG = "soundPool"

    /**
     * 循环方式
     * -1 表示无限循环
     * 0 表示不循环
     * 其他  表示循环多少次
     */
    private val LOOP = 0

    /**
     * 指定播放声音的优先级，数值越高，优先级越大
     */
    private val PRIORITY = 0

    /**
     * 播放速率
     * 1.0的播放率可以使声音按照其原始频率，
     * 而2.0的播放速率，可以使声音按照其 原始频率的两倍播放。
     * 如果为0.5的播放率，则播放速率是原始频率的一半。
     * 播放速率的取值范围是0.5至2.0
     */
    private val RATE = 1f

    private var mainSoundPool: SoundPool? = null

    /**
     * 音频音量值 0 -> 1
     */
    private var volume = 1f
    private var soundId = 0
    private var resId = 0

    /**
     * 加载资源成功
     */
    private var isLoadResourceSuccess = false

    /**
     * 用来保存临时加载的音频ID,防止同一个音频被反复加载消耗内存
     */
    private val soundIdsMap: MutableMap<Int, Int> = HashMap()

    init {
        if (mainSoundPool == null) {
            init()
        }
    }

    /**
     * 播放音频
     *
     * @param resId 音频资源
     */
    fun playSoundWithRedId(resId: Int) {
        this.resId = resId
        if (mainSoundPool == null) {
            init()
        }
        // 音频加载回调
        mainSoundPool!!.setOnLoadCompleteListener { soundPool, sampleId, status -> playSound() }
        //判断字典中是否已加载过音频,加载过直接播放音频id,否则加载音频资源
        if (soundIdsMap.containsKey(resId)) {
            LogX.i(TAG, "已加载过该音频资源,直接播放")
            playSound(soundIdsMap[resId]!!)
        } else {
            //load res
            this.soundId =
                mainSoundPool!!.load(this.mainContext, this.resId, 1)
            soundIdsMap[resId] = soundId
        }
    }

    /**
     * 初始化音频池
     */
    private fun init() {
        // 音频管理器的音频设置调整音量
        val mainAudioManager = mainContext.getSystemService(Context.AUDIO_SERVICE) as AudioManager
        // 当前音量
        val currentVolumeIndex = mainAudioManager.getStreamVolume(STREAM_TYPE).toFloat()
        // 获取最大音量
        val maxVolumeIndex = mainAudioManager.getStreamMaxVolume(STREAM_TYPE).toFloat()
        // 计算当前音量 (0 --> 1)
        this.volume = currentVolumeIndex / maxVolumeIndex
        //设置音频控制器控制的音量类型
        (mainContext as Activity).volumeControlStream =
            STREAM_TYPE

        // API21(5.0)以上
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val audioAttrib = AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_GAME)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build()
            val builder = SoundPool.Builder()
            builder.setAudioAttributes(audioAttrib).setMaxStreams(MAX_STREAMS)
            this.mainSoundPool = builder.build()
        } else {
            // SoundPool(同时播放最大数量, 音频类型, 0)
            this.mainSoundPool = SoundPool(MAX_STREAMS, STREAM_TYPE, 0)
        }
    }

    /**
     * 播放音频
     */
    private fun playSound() {
        isLoadResourceSuccess = true
        playSound(this.soundId)
    }

    /**
     * @param soundId 返回的音频ID,使用load()方法生成Id
     */
    fun playSound(soundId: Int) {
        if (!isLoadResourceSuccess) {
            Log.e(TAG, "请先加载音频资源")
            return
        }
        val leftVolumn = volume
        val rightVolumn = volume
        //play(返回的音频ID,左声道音量,右声道音量,播放声音优先级(数值越高优先级越大),是否循环,播放速率)
        mainSoundPool!!.play(soundId, leftVolumn, rightVolumn, PRIORITY, LOOP, RATE)
    }

    /**
     * 加载音频数据
     *
     * @param resourceList 音频资源
     * @return 返回加载音频后的Id列表
     */
    fun load(resourceList: List<Int?>?): List<Int> {
        if (resourceList == null && resourceList!!.size == 0) {
            isLoadResourceSuccess = false
            return ArrayList()
        }
        //这里去除加载完成的监听
        mainSoundPool!!.setOnLoadCompleteListener(null)
        val soundIds: MutableList<Int> = ArrayList()
        for (i in resourceList!!.indices) {
            val loadId =
                mainSoundPool!!.load(mainContext, resourceList[i]!!, 1)
            soundIds.add(loadId)
        }
        isLoadResourceSuccess = true
        return soundIds
    }

    /**
     * @return 返回对象
     */
    fun getMainSoundPool(): SoundPool? {
        if (mainSoundPool == null) {
            init()
        }
        return mainSoundPool
    }

    /**
     * 释放资源
     */
    fun release() {
        soundIdsMap.clear()
        if (mainSoundPool != null) {
            mainSoundPool!!.release()
            mainSoundPool = null
            isLoadResourceSuccess = false
        }
    }

    companion object {
        /**
         * 能够同时播放的最大音效数,最好不要设置太大
         * 同时播放是指正在播放音频时也可播放其它音频
         */
        private const val MAX_STREAMS = 4

        /**
         * 音频类型
         * STREAM_MUSIC 音乐音频,播放时使用媒体音量
         * STREAM_SYSTEM 系统音频,播放时使用铃声音量
         */
        private const val STREAM_TYPE = AudioManager.STREAM_MUSIC
    }
}
